/**
 * File:		CourseQuery.java
 * Project:		Virtual Advisor
 * Module:		Data Management
 * Author:		Rotem Ganel
 * Created:		April 12, 2011
 * Updated:		April 22, 2011
 * Version:		1 (in progress)
 */

package server.dataManagement.Queries;

public class CourseQuery extends Query {	
	public static enum FIELD {
		ID("<course ID=\"", "\">"),
		Name("<name>", "</name>"),
		Availability("<availability>", "</availability>", COMPLEX_FIELD.Season),
		Credits("<credits>", "</credits>"),
		Requirements("<requirements>", "</requirements>", COMPLEX_FIELD.Prerequisite);
	
		private String beginFlag;
		private String endFlag;
		private COMPLEX_FIELD subField;
		
		/**
		 * Name:			FIELD
		 * Description:		constructs a new FIELD enumeration
		 * PreCondition:	the parameters are well-formed according to the structure of the related repository
		 * PostCondition:	a new FIELD enumeration is instantiated
		 * Parameters:		String beginFlag- the String to search for that precedes the requested data
		 * 					String endFlag- the String to search for that follows the requested data
		 * Notes:			flags are used to find data in the repository to fill the the Queries
		 */
		private FIELD(String beginFlag, String endFlag) {
			this.beginFlag = beginFlag;
			this.endFlag = endFlag;
			this.subField = COMPLEX_FIELD.None;
		}

		/**
		 * Name:			FIELD
		 * Description:		constructs a new complex FIELD enumeration
		 * PreCondition:	the parameters are well-formed according to the structure of the related repository
		 * PostCondition:	a new complex FIELD enumeration is instantiated
		 * Parameters:		String beginFlag- the String to search for that precedes the requested data
		 * 					String endFlag- the String to search for that follows the requested data
		 * 					COMPLEX_FIELD subField- the child FIELD of the FIELD to be created
		 * Notes:			flags are used to find data in the repository to fill the the Queries
		 * 					subFields contain additional flags to locate data contained in the FIELD's children
		 */
		private FIELD(String beginFlag, String endFlag, COMPLEX_FIELD subField) {
			this.beginFlag = beginFlag;
			this.endFlag = endFlag;
			this.subField = subField;
		}
		
		/**
		 * Name:			beginFlag
		 * Description:		returns the beginFlag
		 * PreCondition:	the FIELD is well-formed
		 * PostCondition:	the beginFlag is returned
		 * Parameters:		none
		 * Notes:			none
		 */
		public String beginFlag() {
			return beginFlag;
		}
		
		/**
		 * Name:			endFlag
		 * Description:		returns the endFlag
		 * PreCondition:	the FIELD is well-formed
		 * PostCondition:	the endFlag is returned
		 * Parameters:		none
		 * Notes:			none
		 */
		public String endFlag() {
			return endFlag;
		}
		
		/**
		 * Name:			flags
		 * Description:		returns an array containing the related flags
		 * PreCondition:	the FIELD is well-formed
		 * PostCondition:	an array of flags is returned
		 * Parameters:		none
		 * Notes:			simple FIELDs will return a String[2]: beginFlag, endFlag
		 * 					complex FIELDs will return a String[4]: beginFlag, beginSubFlag, endSubFlag, endFlag
		 */
		public String[] flags() {
			if (!hasSubField()) {
				return new String[]{beginFlag, endFlag};
			} else {
				return new String[]{beginFlag, subField.beginFlag, subField.endFlag, endFlag};
			}
		}
		
		/**
		 * Name:			
		 * Description:		
		 * PreCondition:	
		 * PostCondition:	
		 * Parameters:		
		 * Notes:			
		 */
		public boolean hasSubField() {
			return !subField.equals(COMPLEX_FIELD.None);
		}
		
		private static enum COMPLEX_FIELD {
			Season("<semester season=\"", "\" />"),
			Prerequisite("<prerequisite reference=\"", "\" />"), None(null, null);
			
			public String beginFlag;
			public String endFlag;
			
			/**
			 * Name:			
			 * Description:		
			 * PreCondition:	
			 * PostCondition:	
			 * Parameters:		
			 * Notes:			
			 */
			private COMPLEX_FIELD(String beginFlag, String endFlag) {
				this.beginFlag = beginFlag;
				this.endFlag = endFlag;
			}
		}
	}
		
	private String courseID;
	
	/**
	 * Name:			
	 * Description:		
	 * PreCondition:	
	 * PostCondition:	
	 * Parameters:		
	 * Notes:			
	 */
	public CourseQuery(ACTION action, String courseID) {
		super(action, FIELD.ID.beginFlag + courseID + FIELD.ID.endFlag);
		this.courseID = courseID;
	}

	/**
	 * Name:			
	 * Description:		
	 * PreCondition:	
	 * PostCondition:	
	 * Parameters:		
	 * Notes:			
	 */
	//Duplicates the Query, but leaves the response blank
	public CourseQuery(CourseQuery original) {
		super(original);
		this.courseID = original.courseID;
	}
		
	/**
	 * Name:			
	 * Description:		
	 * PreCondition:	
	 * PostCondition:	
	 * Parameters:		
	 * Notes:			
	 */
	public String QUERY_TYPE() {
		return this.getClass().toString();
	}
	
	public String[][] flags() {
		String[][] flags = new String[FIELD.values().length - 1][];
		
		//Skip over ID
		for (int i = 1; i < FIELD.values().length; i++) {
			flags[i - 1] = FIELD.values()[i].flags();
		}

		return flags;
	}
	
	public boolean respond(String[] response) {
		String[] fullResponse = new String[response.length + 1];
		fullResponse[0] = courseID;
		
		for (int i = 0; i < response.length; i++) {
			fullResponse[i + 1] = response[i];
		}
		
		return super.respond(fullResponse);
	}
}
